/*
 * Copyright 2010-2011 OddRain Copyright 2010 marcus905 <marcus90@gmail.com>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.oddrain.wifieditor.pro;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.PackageInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

public class WifiConfigList extends Activity implements OnSharedPreferenceChangeListener {

    private static final String INT_PRIVATE_KEY = "private_key";
    private static final String INT_PHASE2 = "phase2";
    private static final String INT_PASSWORD = "password";
    private static final String INT_IDENTITY = "identity";
    private static final String INT_EAP = "eap";
    private static final String INT_CLIENT_CERT = "client_cert";
    private static final String INT_CA_CERT = "ca_cert";
    private static final String INT_ANONYMOUS_IDENTITY = "anonymous_identity";
    private static final String INT_ENTERPRISEFIELD_NAME = "android.net.wifi.WifiConfiguration$EnterpriseField";

    private static final int SHOW_PREFERENCES = 0;
    private WifiManager wifi;
    private ListView wifiConfigListView;
    private List<WifiConfiguration> wifiConfigList;
    private WifiConfiguration selectedConfig;
    private WifiConfigurationAdapter aa;
    private boolean editingPrefs = false;

    private void editConfig(final WifiConfiguration selectedConfig) {
        final Context context = getApplicationContext();
        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        prefs.registerOnSharedPreferenceChangeListener(WifiConfigList.this);
        final SharedPreferences.Editor editor = prefs.edit();
        editor.clear();

        if (selectedConfig.SSID != null) {
            editor.putString(WifiConfigSettings.PREF_SSID,
                    selectedConfig.SSID.replaceAll("\"", ""));
        }

        if (selectedConfig.BSSID != null) {
            editor.putString(WifiConfigSettings.PREF_BSSID, selectedConfig.BSSID);
        }

        editor.putBoolean(WifiConfigSettings.PREF_HIDDEN_SSID, selectedConfig.hiddenSSID);

        editor.putBoolean(WifiConfigSettings.PREF_KEY_NONE,
                selectedConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE));
        editor.putBoolean(WifiConfigSettings.PREF_KEY_PSK,
                selectedConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK));
        editor.putBoolean(WifiConfigSettings.PREF_KEY_EAP,
                selectedConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP));
        editor.putBoolean(WifiConfigSettings.PREF_KEY_IEEE,
                selectedConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X));

        editor.putBoolean(WifiConfigSettings.PREF_AUTH_OPEN,
                selectedConfig.allowedAuthAlgorithms.get(WifiConfiguration.AuthAlgorithm.OPEN));
        editor.putBoolean(WifiConfigSettings.PREF_AUTH_LEAP,
                selectedConfig.allowedAuthAlgorithms.get(WifiConfiguration.AuthAlgorithm.LEAP));
        editor.putBoolean(WifiConfigSettings.PREF_AUTH_SHARED,
                selectedConfig.allowedAuthAlgorithms
                        .get(WifiConfiguration.AuthAlgorithm.SHARED));

        editor.putBoolean(WifiConfigSettings.PREF_SEC_WPA,
                selectedConfig.allowedProtocols.get(WifiConfiguration.Protocol.WPA));
        editor.putBoolean(WifiConfigSettings.PREF_SEC_RSN,
                selectedConfig.allowedProtocols.get(WifiConfiguration.Protocol.RSN));

        editor.putBoolean(WifiConfigSettings.PREF_PAIR_NONE,
                selectedConfig.allowedPairwiseCiphers
                        .get(WifiConfiguration.PairwiseCipher.NONE));
        editor.putBoolean(WifiConfigSettings.PREF_PAIR_CCMP,
                selectedConfig.allowedPairwiseCiphers
                        .get(WifiConfiguration.PairwiseCipher.CCMP));
        editor.putBoolean(WifiConfigSettings.PREF_PAIR_TKIP,
                selectedConfig.allowedPairwiseCiphers
                        .get(WifiConfiguration.PairwiseCipher.TKIP));

        editor.putBoolean(WifiConfigSettings.PREF_GRP_WEP40,
                selectedConfig.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.WEP40));
        editor.putBoolean(WifiConfigSettings.PREF_GRP_WEP104,
                selectedConfig.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.WEP104));
        editor.putBoolean(WifiConfigSettings.PREF_GRP_TKIP,
                selectedConfig.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.TKIP));
        editor.putBoolean(WifiConfigSettings.PREF_GRP_CCMP,
                selectedConfig.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.CCMP));

        if (selectedConfig.wepTxKeyIndex > 3 || selectedConfig.wepTxKeyIndex < 0) {
            editor.putInt(WifiConfigSettings.PREF_WEPKEY_IDX, selectedConfig.wepTxKeyIndex);
        }

        if (selectedConfig.wepKeys[0] != null && selectedConfig.wepKeys[0].length() >= 2) {
            editor.putString(WifiConfigSettings.PREF_WEPKEY_KEY0,
                    removeDoubleQuotes(selectedConfig.wepKeys[0]));
        }

        if (selectedConfig.wepKeys[1] != null && selectedConfig.wepKeys[1].length() >= 2) {
            editor.putString(WifiConfigSettings.PREF_WEPKEY_KEY1,
                    removeDoubleQuotes(selectedConfig.wepKeys[1]));
        }

        if (selectedConfig.wepKeys[2] != null && selectedConfig.wepKeys[2].length() >= 2) {
            editor.putString(WifiConfigSettings.PREF_WEPKEY_KEY2,
                    removeDoubleQuotes(selectedConfig.wepKeys[2]));
        }

        if (selectedConfig.wepKeys[3] != null && selectedConfig.wepKeys[3].length() >= 2) {
            editor.putString(WifiConfigSettings.PREF_WEPKEY_KEY3,
                    removeDoubleQuotes(selectedConfig.wepKeys[3]));
        }

        if (selectedConfig.preSharedKey != null && selectedConfig.preSharedKey.length() >= 2) {
            editor.putString(WifiConfigSettings.PREF_WPA_KEY,
                    removeDoubleQuotes(selectedConfig.preSharedKey));
        }

        // Enterprise Settings
        updateEnterpriseSettings(editor);

        editor.commit();
        editingPrefs = true;
    }

    private void updateEnterpriseSettings(final SharedPreferences.Editor editor) {
        // Reflection magic needs to be done here to access non-public APIs
        try {
            final Class<?>[] wcClasses = WifiConfiguration.class.getClasses();
            Class<?> wcEnterpriseField = null;
            boolean noEnterpriseFieldType = false;

            for (final Class<?> wcClass : wcClasses) {
                if (wcClass.getName().equals(INT_ENTERPRISEFIELD_NAME)) {
                    wcEnterpriseField = wcClass;
                    break;
                }
            }
            if (wcEnterpriseField == null) {
                // Cupcake/Donut access enterprise
                // EnterpriseField was added to Android in Donut(2.0)
                noEnterpriseFieldType = true;
            }

            // I know there is enterpriseFields but I haven't gotten around it
            // yet
            // nulls here to workaround the overzealous java compiler
            Field wcefAnonymousId = null;
            Field wcefCaCert = null;
            Field wcefClientCert = null;
            Field wcefEap = null;
            Field wcefIdentity = null;
            Field wcefPassword = null;
            Field wcefPhase2 = null;
            Field wcefPrivateKey = null;
            final Field[] wcefFields = WifiConfiguration.class.getFields();

            // Dispatching Field vars
            for (final Field wcefField : wcefFields) {
                if (wcefField.getName().trim().equals(INT_ANONYMOUS_IDENTITY)) {
                    wcefAnonymousId = wcefField;
                } else if (wcefField.getName().trim().equals(INT_CA_CERT)) {
                    wcefCaCert = wcefField;
                } else if (wcefField.getName().trim().equals(INT_CLIENT_CERT)) {
                    wcefClientCert = wcefField;
                } else if (wcefField.getName().trim().equals(INT_EAP)) {
                    wcefEap = wcefField;
                } else if (wcefField.getName().trim().equals(INT_IDENTITY)) {
                    wcefIdentity = wcefField;
                } else if (wcefField.getName().trim().equals(INT_PASSWORD)) {
                    wcefPassword = wcefField;
                } else if (wcefField.getName().trim().equals(INT_PHASE2)) {
                    wcefPhase2 = wcefField;
                } else if (wcefField.getName().trim().equals(INT_PRIVATE_KEY)) {
                    wcefPrivateKey = wcefField;
                }
            }

            Method wcefValue = null;
            if (!noEnterpriseFieldType) {
                for (final Method m : wcEnterpriseField.getMethods()) {
                    if (m.getName().trim().equals("value")) {
                        wcefValue = m;
                        break;
                    }
                }
            }

            String tVal = null;
            if (noEnterpriseFieldType) {
                tVal = (String)wcefEap.get(selectedConfig);
            } else {
                tVal = (String)wcefValue.invoke(wcefEap.get(selectedConfig), null);
            }
            if (tVal != null) {
                /* selectedConfig.eap.value() */
                editor.putString(WifiConfigSettings.PREF_ENTR_EAP, tVal);
            }

            if (noEnterpriseFieldType) {
                tVal = (String)wcefPhase2.get(selectedConfig);
            } else {
                tVal = (String)wcefValue.invoke(wcefPhase2.get(selectedConfig), null);
            }
            if (tVal != null) {
                editor.putString(WifiConfigSettings.PREF_ENTR_PHASE2, removeDoubleQuotes(tVal));
            }

            if (noEnterpriseFieldType) {
                tVal = (String)wcefIdentity.get(selectedConfig);
            } else {
                tVal = (String)wcefValue.invoke(wcefIdentity.get(selectedConfig), null);
            }

            if (tVal != null) {
                editor.putString(WifiConfigSettings.PREF_ENTR_IDENT, removeDoubleQuotes(tVal));
            }

            if (noEnterpriseFieldType) {
                tVal = (String)wcefAnonymousId.get(selectedConfig);
            } else {
                tVal = (String)wcefValue.invoke(wcefAnonymousId.get(selectedConfig), null);
            }

            if (tVal != null) {
                editor.putString(WifiConfigSettings.PREF_ENTR_ANON_IDENT,
                        removeDoubleQuotes(tVal));
            }

            if (noEnterpriseFieldType) {
                tVal = (String)wcefPassword.get(selectedConfig);
            } else {
                tVal = (String)wcefValue.invoke(wcefPassword.get(selectedConfig), null);
            }

            if (tVal != null) {
                editor.putString(WifiConfigSettings.PREF_ENTR_PASS, removeDoubleQuotes(tVal));
            }

            if (noEnterpriseFieldType) {
                tVal = (String)wcefClientCert.get(selectedConfig);
            } else {
                tVal = (String)wcefValue.invoke(wcefClientCert.get(selectedConfig), null);
            }

            if (tVal != null && tVal.length() >= 2) {
                editor.putString(WifiConfigSettings.PREF_ENTR_CLIENT_CERT,
                        removeDoubleQuotes(tVal));
            }

            if (noEnterpriseFieldType) {
                tVal = (String)wcefCaCert.get(selectedConfig);
            } else {
                tVal = (String)wcefValue.invoke(wcefCaCert.get(selectedConfig), null);
            }

            if (tVal != null && tVal.length() >= 2) {
                editor.putString(WifiConfigSettings.PREF_ENTR_CA_CERT, removeDoubleQuotes(tVal));
            }

            if (noEnterpriseFieldType) {
                tVal = (String)wcefPrivateKey.get(selectedConfig);
            } else {
                tVal = (String)wcefValue.invoke(wcefPrivateKey.get(selectedConfig), null);
            }

            if (tVal != null && tVal.length() >= 2) {
                editor.putString(WifiConfigSettings.PREF_ENTR_PRIV_KEY,
                        removeDoubleQuotes(tVal));
            }
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Setup WiFi
        wifi = (WifiManager)getSystemService(Context.WIFI_SERVICE);
        wifiConfigListView = (ListView)findViewById(R.id.wifiConfigList);

        wifiConfigListView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(final AdapterView<?> _av, final View _v, final int _index,
                    final long arg3) {
                selectedConfig = wifiConfigList.get(_index);

                // Populate Preferences
                editConfig(selectedConfig);

                // Display Preferences
                final Intent i = new Intent(getApplicationContext(), WifiConfigSettings.class);
                i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                startActivityForResult(i, SHOW_PREFERENCES);
            }
        });

        wifiConfigList = new ArrayList<WifiConfiguration>();
        final int resID = R.layout.wificonfiguration_item;
        aa = new WifiConfigurationAdapter(this, resID, wifiConfigList);
        wifiConfigListView.setAdapter(aa);

        final Context context = getApplicationContext();
        context.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(final Context context, final Intent intent) {
                loadWifiConfigs();
                System.out.println("Recieved wifi state changed action:" + intent);
            }
        }, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));

        checkWifiState();
    }

    @Override
    public boolean onCreateOptionsMenu(final Menu menu) {
        final MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.options_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(final MenuItem item) {
        final Builder builder = new AlertDialog.Builder(this);
        switch (item.getItemId()) {
        case R.id.about:
            PackageInfo pi = null;
            try {
                pi = getPackageManager().getPackageInfo(getClass().getPackage().getName(), 0);
            } catch (final Exception e) {
                e.printStackTrace();
                pi = new PackageInfo();
            }
            builder.setTitle(getString(R.string.ABOUT_TITLE));
            builder.setMessage(getString(R.string.ABOUT_CONTENT) + "\n\n" + pi.packageName
                    + "\n" + "v" + pi.versionName + " " + pi.versionCode);
            builder.setPositiveButton(getString(android.R.string.ok), null);
            builder.show();

            return true;
        }
        return false;
    }

    private void loadWifiConfigs() {
        wifiConfigList.clear();
        final List<WifiConfiguration> configs = wifi.getConfiguredNetworks();
        for (final WifiConfiguration config : configs) {
            wifiConfigList.add(config);
        }
        aa.notifyDataSetChanged();
    }

    private void checkWifiState() {
        final boolean enabled = wifi.isWifiEnabled();
        if (!enabled) {
            final Builder builder = new AlertDialog.Builder(this);
            builder.setTitle(getString(R.string.app_name));
            builder.setIcon(android.R.drawable.ic_dialog_alert);
            builder.setMessage(getString(R.string.WIFI_ENABLE_MSG));
            builder.setPositiveButton(getString(R.string.YES), new OnClickListener() {
                @Override
                public void onClick(final DialogInterface dialog, final int which) {
                    wifi.setWifiEnabled(true);
                }
            });
            builder.setNegativeButton(getString(R.string.NO), null);
            builder.show();
        } else {
            loadWifiConfigs();
        }
    }

    @Override
    public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        checkWifiState();
        editingPrefs = false;
    }

    @Override
    public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences,
            final String key) {
        if (editingPrefs) {
            // Save
            saveWiFiConfig();
        }
    }

    private void saveWiFiConfig() {
        // Save Wifi Config from Preferences
        final Context context = getApplicationContext();
        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);

        final String ssid = prefs.getString(WifiConfigSettings.PREF_SSID, null);
        if (ssid != null) {
            selectedConfig.SSID = convertToQuotedString(ssid);
        }

        final String bssid = prefs.getString(WifiConfigSettings.PREF_BSSID, null);
        if (bssid != null && bssid.length() == 17
                && // avoid regex matching if can't be a macaddr
                bssid.matches("[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}")) {
            selectedConfig.BSSID = bssid;
        }

        if (prefs.getBoolean(WifiConfigSettings.PREF_HIDDEN_SSID, false)) {
            selectedConfig.hiddenSSID = true;
        } else {
            selectedConfig.hiddenSSID = false;
        }

        selectedConfig.allowedKeyManagement.clear();
        if (prefs.getBoolean(WifiConfigSettings.PREF_KEY_IEEE, false)) {
            selectedConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_KEY_PSK, false)) {
            selectedConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_KEY_EAP, false)) {
            selectedConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_KEY_NONE, false)) {
            selectedConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
        }

        // GroupCiphers
        selectedConfig.allowedGroupCiphers.clear();
        if (prefs.getBoolean(WifiConfigSettings.PREF_GRP_WEP40, false)) {
            selectedConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_GRP_WEP104, false)) {
            selectedConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_GRP_CCMP, false)) {
            selectedConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_GRP_TKIP, false)) {
            selectedConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
        }

        // PairwiseCiphers
        selectedConfig.allowedPairwiseCiphers.clear();
        if (prefs.getBoolean(WifiConfigSettings.PREF_PAIR_TKIP, false)) {
            selectedConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_PAIR_CCMP, false)) {
            selectedConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_PAIR_NONE, false)) {
            selectedConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.NONE);
        }

        // Authentication Algorithms
        selectedConfig.allowedAuthAlgorithms.clear();
        if (prefs.getBoolean(WifiConfigSettings.PREF_AUTH_OPEN, false)) {
            selectedConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_AUTH_SHARED, false)) {
            selectedConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_AUTH_LEAP, false)) {
            selectedConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.LEAP);
        }

        // Protocols
        selectedConfig.allowedProtocols.clear();
        if (prefs.getBoolean(WifiConfigSettings.PREF_SEC_RSN, false)) {
            selectedConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_SEC_WPA, false)) {
            selectedConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
        }

        // WEP Keys
        final String pIdx = prefs.getString(WifiConfigSettings.PREF_WEPKEY_IDX, "-1");
        final int idx = Integer.parseInt(pIdx);
        if (idx >= 0 && idx <= 3) {
            selectedConfig.wepTxKeyIndex = idx;
        }

        String wepKey = prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY0, null);
        saveWepKey(0, wepKey);

        wepKey = prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY1, null);
        saveWepKey(1, wepKey);

        wepKey = prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY2, null);
        saveWepKey(2, wepKey);

        wepKey = prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY3, null);
        saveWepKey(3, wepKey);

        wepKey = prefs.getString(WifiConfigSettings.PREF_WPA_KEY, null);
        if (wepKey != null) {
            if (wepKey.matches("[0-9A-Fa-f]{64}")) {
                selectedConfig.preSharedKey = wepKey;
            } else {
                selectedConfig.preSharedKey = convertToQuotedString(wepKey);
            }
        }

        // Enterprise Settings
        saveEnterpriseSettings(prefs);

        wifi.updateNetwork(selectedConfig);
        wifi.enableNetwork(selectedConfig.networkId, false);
        wifi.saveConfiguration();
    }

    /**
     * @param key
     * @param wepKey
     */
    private void saveWepKey(final int key, final String wepKey) {
        if (wepKey != null) {
            switch (wepKey.length()) {
            case 10:
            case 26:
            case 58:
                if (wepKey.matches("[0-9A-Fa-f]*")) {
                    selectedConfig.wepKeys[key] = wepKey;
                }
                break;
            default:
                selectedConfig.wepKeys[key] = convertToQuotedString(wepKey);
            }
        }
    }

    private void saveEnterpriseSettings(final SharedPreferences prefs) {
        // Enterprise Settings
        // Reflection magic here too, need access to non-public APIs
        try {
            final Class<?>[] wcClasses = WifiConfiguration.class.getClasses();
            Class<?> wcEnterpriseField = null;
            boolean noEnterpriseFieldType = false;

            for (final Class<?> wcClass : wcClasses) {
                if (wcClass.getName().equals(INT_ENTERPRISEFIELD_NAME)) {
                    wcEnterpriseField = wcClass;
                    break;
                }
            }
            if (wcEnterpriseField == null) {
                // Cupcake/Donut access to enterprise fields
                // EnterpriseField was added to Android in Donut(2.0)
                noEnterpriseFieldType = true;
            }

            // nulls here to workaround the overzealous java compiler
            Field wcefAnonymousId = null, wcefCaCert = null, wcefClientCert = null, wcefEap = null, wcefIdentity = null, wcefPassword = null, wcefPhase2 = null, wcefPrivateKey = null;
            final Field[] wcefFields = WifiConfiguration.class.getFields();
            // Dispatching Field vars
            for (final Field wcefField : wcefFields) {
                if (wcefField.getName().equals(INT_ANONYMOUS_IDENTITY)) {
                    wcefAnonymousId = wcefField;
                } else if (wcefField.getName().equals(INT_CA_CERT)) {
                    wcefCaCert = wcefField;
                } else if (wcefField.getName().equals(INT_CLIENT_CERT)) {
                    wcefClientCert = wcefField;
                } else if (wcefField.getName().equals(INT_EAP)) {
                    wcefEap = wcefField;
                } else if (wcefField.getName().equals(INT_IDENTITY)) {
                    wcefIdentity = wcefField;
                } else if (wcefField.getName().equals(INT_PASSWORD)) {
                    wcefPassword = wcefField;
                } else if (wcefField.getName().equals(INT_PHASE2)) {
                    wcefPhase2 = wcefField;
                } else if (wcefField.getName().equals(INT_PRIVATE_KEY)) {
                    wcefPrivateKey = wcefField;
                }
            }

            Method wcefSetValue = null;
            if (!noEnterpriseFieldType) {
                for (final Method m : wcEnterpriseField.getMethods()) {
                    if (m.getName().trim().equals("setValue")) {
                        wcefSetValue = m;
                    }
                }
            }

            String tVal = prefs.getString(WifiConfigSettings.PREF_ENTR_EAP, null);
            if (tVal != null) {
                if (!noEnterpriseFieldType) {
                    wcefSetValue.invoke(wcefEap.get(selectedConfig), tVal);
                } else {
                    wcefEap.set(selectedConfig, tVal);
                }

            }
            tVal = prefs.getString(WifiConfigSettings.PREF_ENTR_PHASE2, null);
            if (tVal != null) {
                if (!noEnterpriseFieldType) {
                    wcefSetValue.invoke(wcefPhase2.get(selectedConfig), tVal);
                } else {
                    wcefPhase2.set(selectedConfig, convertToQuotedString(tVal));
                }
            }

            tVal = prefs.getString(WifiConfigSettings.PREF_ENTR_IDENT, null);
            if (tVal != null) {
                if (!noEnterpriseFieldType) {
                    wcefSetValue.invoke(wcefIdentity.get(selectedConfig), tVal);
                } else {
                    wcefIdentity.set(selectedConfig, convertToQuotedString(tVal));
                }

            }

            tVal = prefs.getString(WifiConfigSettings.PREF_ENTR_ANON_IDENT, null);
            if (tVal != null) {
                if (!noEnterpriseFieldType) {
                    wcefSetValue.invoke(wcefAnonymousId.get(selectedConfig), tVal);
                } else {
                    wcefAnonymousId.set(selectedConfig, convertToQuotedString(tVal));
                }

            }
            tVal = prefs.getString(WifiConfigSettings.PREF_ENTR_PASS, null);
            if (tVal != null) {
                if (!noEnterpriseFieldType) {
                    wcefSetValue.invoke(wcefPassword.get(selectedConfig), tVal);
                } else {
                    wcefPassword.set(selectedConfig, convertToQuotedString(tVal));
                }

            }

            tVal = prefs.getString(WifiConfigSettings.PREF_ENTR_CLIENT_CERT, null);
            if (tVal != null) {
                if (!noEnterpriseFieldType) {
                    wcefSetValue.invoke(wcefClientCert.get(selectedConfig), tVal);
                } else {
                    wcefClientCert.set(selectedConfig, convertToQuotedString(tVal));
                }

            }

            tVal = prefs.getString(WifiConfigSettings.PREF_ENTR_CA_CERT, null);
            if (tVal != null) {
                if (!noEnterpriseFieldType) {
                    wcefSetValue.invoke(wcefCaCert.get(selectedConfig), tVal);
                } else {
                    wcefCaCert.set(selectedConfig, convertToQuotedString(tVal));
                }
            }

            tVal = prefs.getString(WifiConfigSettings.PREF_ENTR_PRIV_KEY, null);
            if (tVal != null) {
                if (!noEnterpriseFieldType) {
                    wcefSetValue.invoke(wcefPrivateKey.get(selectedConfig), tVal);
                } else {
                    wcefPrivateKey.set(selectedConfig, convertToQuotedString(tVal));
                }
            }
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * Removes the '"' surrounding a string if they exist.
     * 
     * @param string
     * @return
     */
    private static String removeDoubleQuotes(final String string) {
        final int length = string.length();
        if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
            return string.substring(1, length - 1);
        }
        return string;
    }

    /**
     * Adds the '"' surrounding a string if they don't currently exist.
     * 
     * @param string
     * @return
     */
    private static String convertToQuotedString(final String string) {
        final int length = string.length();
        if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
            return string;
        }
        return "\"" + string + "\"";
    }
}